﻿using AutoMapper;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using MDT.LifeSewagePlatform.InterfaceService;
using MDT.LifeSewagePlatform.IRepository;
using MDT.LifeSewagePlatform.Entity;
using MDT.LifeSewagePlatform.Conmmon;
using System.IO;
using System.Threading;

namespace MDT.LifeSewagePlatform.Service
{
    public class FileService : BaseService, IFileService
    {
        #region 下层基础服务
        [Autowired]
        private IFileRepository fileRepository { get; set; }
        [Autowired]
        private IDetailRepository detailRepository { get; set; }

        [Autowired]
        private IMapper mapper { get; set; }
        [Autowired]
        private IDrugRepository drugRepository { get; set; }
        [Autowired]
        private IDrugDetailRepository drugDetailRepository { get; set; }
        [Autowired]
        private IExcelHelper excelHelper { get; set; }
        [Autowired]
        private IAlarmPlaceRepository alarmPlaceRepository { get; set; }
        [Autowired]
        private ISendPhoneNumberMsg sendPhone { get; set; }
        [Autowired]
        private IConfiguration configuration { get; set; }
        [Autowired]
        private IAlarmRepository alarmRepository { get; set; }
        [Autowired]
        private ISendEmail sendEmail { get; set; }
        [Autowired]
        private ICompanyRepository companyRepository { get; set; }
        [Autowired]
        private IDrugDayRespository drugDayRepository { get; set; }
        [Autowired]
        private IRegionRepository regionRepository { get; set; }

        [Autowired]
        private IRuleCompanyRepository ruleCompanyRepository { get; set; }
        public FileService()
        {
        }
        #endregion

        #region method service
        public async Task<BaseMessage> Add(AddFile model, int UserID)
        {

            #region params verify  
            if (model.File == null)
            {
                return BadRequest400("请选择文件!");
            }
            var verifyResualt = model.Verify();
            if (verifyResualt.Item2 == false)
            {
                return BadRequest400(verifyResualt.Item1);
            }
            #endregion
            #region 初次上传 检查上月是否存在上涨次数

            int NowQuarter = DateTime.Now.Month.GetQuarter();
            var query = from drug in drugDetailRepository._dbContext.DrugDetail select drug;

            if (await query.Where(d => d.MonitorTime.Year == DateTime.Now.Year && d.Quarter == NowQuarter).AnyAsync() == false)
            {
                var queryAlarm = await drugDetailRepository._dbContext.AlaramPlace.AsNoTracking().Where(a => a.RoseCount == 1).ToListAsync();
                foreach (var item in queryAlarm)
                {
                    if (item.PresentMonth == 1)
                    {
                        item.RoseCount++;
                        item.PresentMonth = 0;
                    }
                    else
                    {
                        item.RoseCount = 0;
                    }
                    await alarmPlaceRepository.Update(item, UserID);
                }
                await alarmPlaceRepository.SaveChangesAsync();
            }

            #endregion

            #region 添加数据库部分

            bool IsOk = false;
            int quarter = 0;
            DateTime date = DateTime.Now;
            FileEntity fileEntity = mapper.Map<FileEntity>(model);
            using (var dbtra = alarmRepository._dbContext.Database.BeginTransaction())
            {
                List<RegionEntity> areas = null;
                if (await companyRepository.GetCompanies(c => c.ID == model.CompanyID).AnyAsync())
                {
                    var companyView = await companyRepository.GetCompanies(c => c.ID == model.CompanyID).FirstOrDefaultAsync();
                    if (Auth(companyView.PlaceTypeName, -1))
                    {
                        areas = await regionRepository.Where(t => t.ParentID == model.CityID).ToListAsync();
                    }
                    else
                    {
                        areas = await regionRepository.Where(t => t.ID == companyView.AreaID).ToListAsync();
                    }
                }
                else
                {
                    return BadRequest400("请填写正确的委托机构!");
                }
                fileEntity.FileSize = Math.Round((double)model.File.Length / (1024 * 1024), 2);
                fileEntity.UserID = UserID;
                List<DrugDetailEntity> drugEntitys = new List<DrugDetailEntity>();
                List<DrugEntity> drugs = new List<DrugEntity>();
                List<DetailEntity> placetype = await detailRepository.Where(t => t.MainID == (int)eDictionaryType.LevelRegion).ToListAsync(); ;
                List<DrugDayEntity> drugdays = new List<DrugDayEntity>();
                await fileRepository.Create(fileEntity, UserID);
                IsOk = await fileRepository.SaveChangesAsync();
                foreach (var item in await excelHelper.GetExcelList<AddDrug>(model.File.OpenReadStream()))
                {
                    DrugEntity dg = mapper.Map<DrugEntity>(item);
                    dg.PlaceTypeID = placetype.Where(p => p.RowName.Contains(item.PlaceTypeName)).FirstOrDefault().ID;
                    if (item.AreaName == "市")
                    {
                        dg.AreaID = -1;
                    }
                    else
                    {
                        dg.AreaID = areas.Where((a) => a.DisplayName == item.AreaName).FirstOrDefault().ID;
                    }
                    dg.FileID = fileEntity.ID;
                    dg.Quarter = dg.MonitorTime.Month.GetQuarter();
                    date = dg.MonitorTime;
                    quarter = dg.Quarter;

                    dg.CompanyID = model.CompanyID;
                    drugs.Add(dg);
                }
                await drugRepository.Create(drugs, UserID);
                IsOk = await drugRepository.SaveChangesAsync();
                int index = 0;
                foreach (var item in await excelHelper.GetExcelList<AddDrugDetail>())
                {
                    if (index <= drugs.Count)
                    {
                        DrugDetailEntity dgdetail = mapper.Map<DrugDetailEntity>(item);
                        dgdetail.PlaceTypeID = placetype.Where(p => p.RowName.Contains(item.PlaceTypeName)).FirstOrDefault().ID;
                        if (item.AreaName == "市")
                        {
                            dgdetail.AreaID = -1;
                        }
                        else
                        {
                            dgdetail.AreaID = areas.Where((a) => a.DisplayName == item.AreaName).FirstOrDefault().ID;
                        }
                        dgdetail.drugid = drugs[index].ID;
                        dgdetail.FileID = fileEntity.ID;
                        dgdetail.Quarter = dgdetail.MonitorTime.Month.GetQuarter();
                        dgdetail.CompanyID = model.CompanyID;
                        dgdetail.PlaceTypeID = placetype.Where(p => p.RowName.Contains(item.PlaceTypeName)).FirstOrDefault().ID;
                        drugEntitys.Add(dgdetail);
                    }
                    index++;
                }
                await drugDetailRepository.Create(drugEntitys, UserID);
                IsOk = await drugDetailRepository.SaveChangesAsync();

                foreach (AddDrugDayDto item in await excelHelper.GetExcelList<AddDrugDayDto>())
                {
                    DrugDayEntity drugDay = mapper.Map<DrugDayEntity>(item);
                    drugDay.PlaceTypeID = placetype.Where(p => p.RowName.Contains(item.PlaceTypeName)).FirstOrDefault().ID;
                    if (item.AreaName == "市")
                    {
                        drugDay.AreaID = -1;
                    }
                    else
                    {
                        drugDay.AreaID = areas.Where((a) => a.DisplayName == item.AreaName).FirstOrDefault().ID;
                    }
                    drugDay.FileID = fileEntity.ID;
                    drugDay.Quarter = drugDay.MonitorTime.Month.GetQuarter();
                    drugDay.CompanyID = model.CompanyID;
                    drugDay.PlaceTypeID = placetype.Where(p => p.RowName.Contains(item.PlaceTypeName)).FirstOrDefault().ID;
                    drugdays.Add(drugDay);
                }

                await drugDayRepository.Create(drugdays, UserID);
                IsOk = await drugDetailRepository.SaveChangesAsync();
                #endregion
                if (IsOk)
                {
                    dbtra.Commit();
                }
                else
                {
                    dbtra.Rollback();
                }
            }
            if (IsOk)
            {
                Alarm(UserID);
                await Analyaze(fileEntity.CompanyID, quarter, fileEntity.CityID, date);
                string dic = configuration["SewageExcelDataPath"];
                await SaveFile(model.File, Path.Combine(dic, model.CompanyID.ToString(), model.CityID.ToString()), fileEntity.ID.ToString(), (extension) => extension.Contains(".xlsx") || extension.Contains(".xls"));
                return Ok200("添加成功!");
            }
            return BadRequest400("添加失败!");
        }

        public async Task<BaseMessage> Update(UpdateFile model, int ID, int UserID)
        {
            FileEntity fileEntity = await fileRepository.FirstOrDefaultAsync(f => f.IsDelete == false && f.ID == ID);
            mapper.Map(model, fileEntity);
            var entity = await fileRepository.Update(fileEntity, UserID);
            if (await fileRepository.SaveChangesAsync())
            {
                return Ok200("更新文件!");
            }
            return BadRequest400("文件更新失败!");

        }

        public async Task<BaseMessage> SoftDelete(int ID, int UserID)
        {
            if (await fileRepository.AnyAsync(t => t.ID == ID) == false)
            {
                return BadRequest400("文件编号不存在删除失败");
            }
            FileEntity fileEntity = await fileRepository.FirstOrDefaultAsync(t => t.ID == ID);
            string dic = Path.Combine(configuration["SewageExcelDataPath"], fileEntity.CompanyID.ToString(), fileEntity.CityID.ToString());
            foreach (var item in Directory.GetFiles(dic))
            {
                System.IO.File.Delete(item);
            }

            await drugDetailRepository.Delete(d => d.FileID == ID);
            await drugRepository.Delete(d => d.FileID == ID);
            await fileRepository.Delete(f => f.ID == ID);
            if (await fileRepository.SaveChangesAsync())
            {
                return Ok200("文件删除成功!");
            }
            return BadRequest400("文件删除失败!");

        }

        public async Task<BaseMessage> GetFiles(FileParameter Params)
        {
            IQueryable<FileView> fileViews = fileRepository.GetFiles(f => true);
            return Ok200("查询成功!", await PageList<FileView>.CreateAsync(fileViews, Params));
        }

        /// <summary>
        /// 发送
        /// </summary>
        /// <param name="verifyType"></param>
        /// <param name="val"></param>
        /// <param name="emailaddr"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        private async Task<bool> Send(int verifyType, ValueModel val, string emailaddr, string content)
        {
            AuthModel authModel = configuration.GetSection("txAuthSendPhone").Get<AuthModel>();
            EmailModel emailModel = configuration.GetSection("EmailConfig").Get<EmailModel>();
            bool EmailOk = false;
            bool PhoneOK = false;
            switch (verifyType)
            {
                case (int)VerifyType.Email:
                    if (emailModel == null)
                    {
                        return false;
                    }
                    return await sendEmail.SendMessage(emailModel, emailaddr, content, emailaddr);

                case (int)VerifyType.Phone:
                    if (authModel == null)
                    {
                        return false;
                    }
                    return await sendPhone.Send(authModel, val);

                case (int)VerifyType.EmailAndPhone:
                    if (authModel != null)
                    {
                        PhoneOK = await sendPhone.Send(authModel, val);
                    }
                    if (emailModel != null)
                    {
                        EmailOk = await sendEmail.SendMessage(emailModel, emailaddr, content, emailaddr);
                    }
                    break;
                default:
                    break;
            }

            return EmailOk && PhoneOK;
        }
        /// <summary>
        /// 发送预警
        /// </summary>
        /// <param name="UserID"></param>
        private void Alarm(int UserID)
        {
            int NowQuarter = DateTime.Now.Month.GetQuarter();
            Task.Run(async () =>
            {
                #region 超过预警值发送警报
                var AlarmTypeDate = await detailRepository.Where(d => d.MainID == 8).ToListAsync();
                var placeDutys = await drugDetailRepository._dbContext.PlaceDutys.AsNoTracking().Where(dp => dp.IsDelete == false).ToListAsync();
                var confgAram = from alarm in drugDetailRepository._dbContext.SetAlarm.AsNoTracking()
                                join moreyellow in drugDetailRepository._dbContext.Details.AsNoTracking() on alarm.MoreYellowID equals moreyellow.ID
                                join morered in drugDetailRepository._dbContext.Details.AsNoTracking() on alarm.MoreRedID equals morered.ID
                                join moreonceyellow in drugDetailRepository._dbContext.Details.AsNoTracking() on alarm.MoreOnceYellowID equals moreonceyellow.ID
                                join moreoncered in drugDetailRepository._dbContext.Details.AsNoTracking() on alarm.MoreOneceRedID equals moreoncered.ID
                                join verify in drugDetailRepository._dbContext.Details.AsNoTracking() on alarm.VerifyTypeID equals verify.ID
                                select new
                                {
                                    MoreYellowValue = moreyellow.RowDesc,
                                    MoreRedValue = morered.RowDesc,
                                    MoreOnceRedValue = moreoncered.RowDesc,
                                    MoreOnceYellowValue = moreonceyellow.RowDesc,
                                    StandardValue = alarm.StandardValue,
                                    IsUserMore = alarm.IsUserMore,
                                    IsUserOnce = alarm.IsUserOnce,
                                    VerifyType = verify.RowID
                                };
                var confgAramData = await confgAram.FirstOrDefaultAsync();

                var presentQuery = from drug in drugDetailRepository.GetQuery().Where(d => d.MonitorTime.Year == DateTime.Now.Year && d.Quarter >= NowQuarter - 1)
                                   join alarm in drugDetailRepository._dbContext.AlaramPlace.AsNoTracking() on drug.AreaID equals alarm.AreaID
                                   select new
                                   {
                                       AreaID = drug.AreaID,
                                       MonitorTime = drug.MonitorTime,
                                       ReducedTotal = drug.ReducedTotal,
                                       PresentMonth = alarm.PresentMonth,
                                       RoseCount = alarm.RoseCount,
                                       Quarter = drug.Quarter
                                   };
                var AlarmKeyValue = alarmPlaceRepository.GetQuery().ToDictionary(t => t.AreaID.ToString(), t => new AlaramPlaceEntity()
                { ID = t.ID, PresentMonth = t.PresentMonth, RoseCount = t.RoseCount, AreaID = t.AreaID });

                var presentDate = await presentQuery.GroupBy(t => new { t.AreaID, t.Quarter }).Select(d => new
                {
                    Avg = d.Average(t => t.ReducedTotal),
                    AreaID = d.Key.AreaID,
                    Quarter = d.Key.Quarter,


                }).ToListAsync();

                for (int i = 0; i < presentDate.Count; i++)
                {
                    if (presentDate[i].AreaID == presentDate[i + 1].AreaID)
                    {
                        bool sendOK = false;
                        PlaceDutyEntity placeDuty = placeDutys.Where(t => t.AreaID == presentDate[i].AreaID).FirstOrDefault();
                        double upValue = (presentDate[i + 1].Avg - presentDate[i].Avg);
                        double upStand = (presentDate[i + 1].Avg - confgAramData.StandardValue) / confgAramData.StandardValue;
                        double upStandPercent = Math.Round(upStand * 100, 2);
                        if (confgAramData.IsUserMore && upStand > double.Parse(confgAramData.MoreYellowValue))
                        {
                            ValueModel vmodel = new ValueModel();
                            AlaramEntity alarmEntity = new AlaramEntity();
                            string msg = string.Empty;
                            alarmEntity.AreaID = presentDate[i].AreaID;
                            if (upStand > double.Parse(confgAramData.MoreRedValue))
                            {
                                //发红色
                                alarmEntity.DutyID = placeDuty.ID;
                                alarmEntity.AlarmTypeID = AlarmTypeDate.Where(atype => atype.RowID == 2).FirstOrDefault().ID;
                                vmodel.PhoneNumbers = new string[] { placeDuty.PhoneNumber };
                                vmodel.Parametes = new string[] { "红色", Math.Round(presentDate[i + 1].Avg, 2).ToString(), $"超过标准值{Math.Round(upStandPercent, 1)}%;" };
                                sendOK = await Send(confgAramData.VerifyType, vmodel, placeDuty.Email, $"红色预警:本月折算值{Math.Round(presentDate[i + 1].Avg, 2).ToString()},超过标准值{Math.Round(upStandPercent, 1)}%;");
                                msg = $"毒情综合指标超过标准{upStandPercent}%";
                            }
                            else
                            {
                                //发黄色警告
                                alarmEntity.AlarmTypeID = AlarmTypeDate.Where(atype => atype.RowID == 1).FirstOrDefault().ID;
                                alarmEntity.DutyID = placeDuty.ID;
                                vmodel.PhoneNumbers = new string[] { placeDuty.PhoneNumber };
                                vmodel.Parametes = new string[] { "黄色", Math.Round(presentDate[i + 1].Avg, 2).ToString(), $"超过标准值{Math.Round(upStandPercent, 1)}%;" };
                                sendOK = await Send(confgAramData.VerifyType, vmodel, placeDuty.Email, $"黄色预警:本月折算值{Math.Round(presentDate[i + 1].Avg, 2).ToString()},超过标准值{Math.Round(upStandPercent, 1)}%;");
                                msg = $"毒情综合指标超过标准{upStandPercent}%";
                            }
                            alarmEntity.Msg = msg;
                            alarmEntity.Date = DateTime.Now;
                            await alarmRepository.Create(alarmEntity, UserID);
                        }
                        if (confgAramData.IsUserOnce && upValue > 0)
                        {
                            //记录上涨次数

                            ValueModel vmodel = new ValueModel();
                            AlaramPlaceEntity item = AlarmKeyValue[presentDate[i].AreaID.ToString()];
                            item.PresentMonth = 1;

                            AlaramEntity alarmEntity = new AlaramEntity();
                            alarmEntity.AreaID = presentDate[i].AreaID;
                            string msg = string.Empty;

                            if (item.RoseCount + item.PresentMonth >= double.Parse(confgAramData.MoreOnceYellowValue))
                            {
                                if (item.RoseCount + item.PresentMonth >= double.Parse(confgAramData.MoreRedValue))
                                {
                                    //上涨次数红色警报
                                    alarmEntity.AlarmTypeID = AlarmTypeDate.Where(atype => atype.RowID == 2).FirstOrDefault().ID;
                                    vmodel.PhoneNumbers = new string[] { placeDuty.PhoneNumber };
                                    vmodel.Parametes = new string[] { "红色", Math.Round(presentDate[i + 1].Avg, 2).ToString(), $"已经连续上涨{item.RoseCount};" };

                                    sendOK = await Send(confgAramData.VerifyType, vmodel, placeDuty.Email, $"红色预警:本月折算值{Math.Round(presentDate[i + 1].Avg, 2).ToString()},已经连续上涨{item.RoseCount};");

                                    alarmEntity.DutyID = placeDuty.ID;
                                    msg = $"毒情连续上涨{item.RoseCount + item.PresentMonth}，大于红色预警次数;";

                                }
                                else
                                {
                                    //上涨次数黄色警报
                                    alarmEntity.DutyID = placeDuty.ID;
                                    alarmEntity.AlarmTypeID = AlarmTypeDate.Where(atype => atype.RowID == 1).FirstOrDefault().ID;
                                    vmodel.PhoneNumbers = new string[] { placeDuty.PhoneNumber };
                                    vmodel.Parametes = new string[] { "黄色", Math.Round(presentDate[i + 1].Avg, 2).ToString(), $"超过标准值{item.RoseCount};" };
                                    sendOK = await Send(confgAramData.VerifyType, vmodel, placeDuty.Email, $"黄色预警:本月折算值{Math.Round(presentDate[i + 1].Avg, 2).ToString()},已经连续上涨{item.RoseCount};");
                                    msg = $"毒情连续上涨{item.RoseCount + item.PresentMonth}，大于黄色预警次数;";
                                }
                                alarmEntity.Msg = msg;
                                alarmEntity.Date = DateTime.Now;
                                await alarmRepository.Create(alarmEntity, UserID);
                            }
                        }
                        if (sendOK == false)
                        {
                        }
                    }
                    i++;
                }
                await alarmRepository.SaveChangesAsync();
                #endregion
            }).Wait();
        }

        /// <summary>
        /// 生成预警上涨信息
        /// </summary>
        /// <param name="CompanyID"></param>
        /// <param name="Quarter"></param>
        /// <param name="CityID"></param>
        /// <param name="Date"></param>
        /// <returns></returns>
        /// 




        private async Task Analyaze(int CompanyID, int Quarter, int CityID, DateTime Date)
        {

            int[] PastQuarter = new int[1] { Quarter };
            int[] PastYear = new int[1] { Date.Year };
            int[] PastMonth = new int[1] { Date.Month };


            var rules = await ruleCompanyRepository.GetRuleCompany(t => t.IsDelete.Equals(false) && t.Enable.Equals(false) && t.CompanyID.Equals(CompanyID)).ToListAsync();
            List<DetailEntity> changes = alarmRepository._dbContext.Details.AsNoTracking().Where(t => t.MainID == (int)DetailType.Change).ToList();
            //找出前三季度
            for (int i = 0; i < 1; i++)
            {
                if (i == 0)
                {
                    if (_systemConfig.QuarterOrMonth == (int)eGroupGetDateType.Quarter)
                    {
                        PastYear[i] = Quarter.GetByPastQuarterYear(Date.Year);
                    }
                    else
                    {
                        PastYear[i] = Date.Month.GetPastYearByMonth(Date.Year);
                    }
                    PastQuarter[i] = Quarter.GetPastQuarter();
                    PastMonth[i] = Date.Month.GetPastMonth();
                }
                else
                {
                    if (_systemConfig.QuarterOrMonth == (int)eGroupGetDateType.Quarter)
                    {
                        PastYear[i] = Quarter.GetByPastQuarterYear(Date.Year);
                    }
                    else
                    {
                        PastYear[i] = Date.Month.GetPastYearByMonth(Date.Year);
                    }
                    PastQuarter[i] = PastQuarter[i - 1].GetPastQuarter();
                    PastMonth[i] = PastMonth[i - 1].GetPastMonth();
                }
            }
            PipeLineParameter pipeLineParams = new PipeLineParameter()
            {
                Month = Date.Month,
                Year = Date.Year,
                Quarter = Quarter,
            };

            PipeLineMoreParameter pipeLieMoreParams = new PipeLineMoreParameter()
            {
                Years = PastYear,
                Months = PastMonth,
                Quarters = PastQuarter,
            };
            var query = drugDetailRepository.GetDrugDetails(t => t.CompanyID == CompanyID && t.CityID == CityID);

            if (QueryPipeLineTime(pipeLieMoreParams, query).Any() == false)
            {
                _logger.LogWarning("系统中没有找到关于前三季度的数据!");
                return;
            }

            if ((await QueryPipeLineTime(pipeLineParams, query.Where(t => t.MonitorTime.Year == Date.Year))).Any() == false)
            {
                _logger.LogWarning("当前季度数据无,重新尝试上传!");
                return;
            }

            //QueryPipeLineTime(query);

            var GroupDrugData = (await QueryPipeLineTime(pipeLineParams, query.Where(t => t.MonitorTime.Year == Date.Year)))
               .GroupBy(t => new { t.MonitoringSite, t.AreaID })
               .Select(t => new DrugDetailEntity()
               {
                   Cocaine = t.Average(t => t.Cocaine),
                   Cyclohexanone = t.Average(t => t.Cyclohexanone),
                   Diamorphine = t.Average(t => t.Diamorphine),
                   Ecstasy = t.Average(t => t.Ecstasy),
                   Ketamine = t.Average(t => t.Ketamine),
                   Methylamphetamine = t.Average(t => t.Methylamphetamine),
                   MonitoringSite = t.Key.MonitoringSite,
                   ReducedTotal = t.Average(t => t.ReducedTotal),
                   AreaID = t.Key.AreaID
               }).ToList();
            //query.Where(t=>t.MonitorTime.Year==Date.Year && t.CompanyID==CompanyID && t.Quarter==Quarter && t.CityID==CityID)
            //.GroupBy(t=>new {t.MonitoringSite,t.AreaID})
            //.Select(t=>new DrugDetailEntity() {
            //Cocaine=t.Average(t=>t.Cocaine),
            //Cyclohexanone=t.Average(t=>t.Cyclohexanone),
            //Diamorphine=t.Average(t=>t.Diamorphine),
            //Ecstasy=t.Average(t=>t.Ecstasy),
            //Ketamine=t.Average(t=>t.Ketamine),
            //Methylamphetamine=t.Average(t=>t.Methylamphetamine),
            //MonitoringSite=t.Key.MonitoringSite,
            //ReducedTotal=t.Average(t=>t.ReducedTotal),
            //AreaID=t.Key.AreaID
            //}).ToList();
            var GroupPastDrugData = QueryPipeLineTime(pipeLieMoreParams, query)
               .GroupBy(t => new { t.MonitoringSite, t.AreaID })
               .Select(t => new DrugDetailEntity()
               {
                   Cocaine = t.Average(t => t.Cocaine),
                   Cyclohexanone = t.Average(t => t.Cyclohexanone),
                   Diamorphine = t.Average(t => t.Diamorphine),
                   Ecstasy = t.Average(t => t.Ecstasy),
                   Ketamine = t.Average(t => t.Ketamine),
                   Methylamphetamine = t.Average(t => t.Methylamphetamine),
                   MonitoringSite = t.Key.MonitoringSite,
                   ReducedTotal = t.Average(t => t.ReducedTotal),
                   AreaID = t.Key.AreaID
               }).ToList();
            List<AlaramEntity> alarms = alarmRepository._dbContext.Alarm.Where(t => t.CompanyID == CompanyID && t.Date.Year == Date.Year && t.Quarter == Quarter && t.CityID == CityID).ToList();
            var cityDrug = GroupDrugData.FirstOrDefault(t => t.AreaID.Equals(-1) && t.MonitoringSite == "市");
            var areas = GroupDrugData.Where(t => !t.AreaID.Equals(-1) && !(t.MonitoringSite == "市"));
            var pastCityDrug = GroupPastDrugData.FirstOrDefault(t => t.AreaID.Equals(-1) && t.MonitoringSite == "市");
            var pastareas = GroupPastDrugData.FirstOrDefault(t => !t.AreaID.Equals(-1) && !(t.MonitoringSite == "市"));
            Type type = typeof(DrugDetailEntity);

            if (rules != null && rules.Any())
            {
                foreach (var item in areas)
                {
                    AlaramEntity alarm = new AlaramEntity();

                    if (GroupPastDrugData.Where(t => t.MonitoringSite == item.MonitoringSite).Any() == true)
                    {
                        DrugDetailEntity drugDetail = GroupPastDrugData.Where(t => t.MonitoringSite == item.MonitoringSite).FirstOrDefault();
                        foreach (var drugProp in type.GetProperties().Where(t => t.PropertyType == typeof(double)))
                        {
                            double value = 0;
                            double.TryParse(drugProp.GetValue(item).ToString(), out value);

                            double pastValue = 0;
                            double.TryParse(drugProp.GetValue(drugDetail).ToString(), out pastValue);

                            double cityValue = 0;
                            double.TryParse(drugProp.GetValue(cityDrug).ToString(), out cityValue);
                            double percent;
                            double Pastpercent;
                            if (drugProp.GetColName().Contains("折算总量"))
                            {
                                //1.当前对比
                                percent = value.GetPercent(cityValue);

                                //2过去对比
                                Pastpercent = value.GetPercent(cityValue);
                            }
                            else
                            {
                                //1.当前对比
                                percent = value.GetPercent(cityValue);

                                //2过去对比
                                Pastpercent = value.GetPercent(cityValue);
                            }

                            alarm.CityID = CityID;
                            alarm.CompanyID = CompanyID;
                            alarm.Date = Date;
                            alarm.Quarter = Quarter;
                            alarm.AreaID = item.AreaID;
                            alarm.RecordDate = DateTime.Now;
                            alarm.MonitoringSite = item.MonitoringSite;
                            alarm.Msg = $"{percent.GetPercentDesc()}";
                            await alarmRepository.Create(alarm, 0);
                            await alarmRepository.SaveChangesAsync();

                        }
                    }
                    await alarmRepository.SaveChangesAsync();
                }
            }
        }
        #endregion
    }
}
